package com.yunhoo.contract.db.impl;

import com.ibatis.sqlmap.client.SqlMapClient;
import com.yunhoo.checkFlow.db.impl.CheckFlowImpl;
import com.yunhoo.contract.bean.FileUploadBean;
import com.yunhoo.contract.model.ContractContent;
import com.yunhoo.contract.model.ContractDocument;
import com.yunhoo.contract.model.ContractItem;
import com.yunhoo.contract.model.Duty;
import com.yunhoo.contract.model.MainInformation;
import com.yunhoo.contract.model.Matter;
import com.yunhoo.contract.model.PayInformation;
import com.yunhoo.cqq.model.DocumentType;
import com.yunhoo.sys.db.util.IbatisTemplate;
import com.yunhoo.sys.util.common.FacesUtils;
import com.yunhoo.sys.util.common.LoginParam;
import com.yunhoo.sys.util.common.Null;
import java.io.File;
import java.math.BigDecimal;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.logging.Level;
import java.util.logging.Logger;

/**
 *
 * @author cw
 */
public class ContractImpl {

    private static final String NAMESPACE = "contractnamespace.";
    private static final String NAMESPACE_DOC = "docContract.";

    /* 合同附件 */
    public static List<ContractDocument> queryDocList(String number) {
        Map map = new HashMap();
        map.put("orgCode", LoginParam.getOrg().getCode());
        map.put("number", number);
        List<ContractDocument> list = IbatisTemplate.queryForList(NAMESPACE_DOC + "queryDocList", map);
        if (list != null && list.size() > 0) {
            for (ContractDocument doc : list) {
                File file = new File(doc.getUrl());
                if (file.exists()) {
                    doc.setShowflag(true);
                } else {
                    doc.setShowflag(false);
                }

            }
        }
        return list;
    }

    public static List<Integer> queryDocParam(String number) {
        Map map = new HashMap();
        map.put("orgCode", LoginParam.getOrg().getCode());
        map.put("number", number);
        return IbatisTemplate.queryForList(NAMESPACE_DOC + "queryDocParam", map);
    }

    public static void saveDoc(SqlMapClient client, String number, List<ContractDocument> docList) throws SQLException {
        Map map = new HashMap();
        map.put("orgCode", LoginParam.getOrg().getCode());
        map.put("contractId", number);
        for (ContractDocument document : docList) {

            Integer id = (Integer) client.insert(NAMESPACE_DOC + "insertDocument", document);

            System.out.println(" * * * " + "docId = " + id + "  * * * ");

            map.put("docId", id);

            client.insert(NAMESPACE + "insertDocRelation", map);
            System.out.println(" * * * " + "saveDoc over" + "  * * * ");
        }
    }

    public static boolean deleteDoc(String number, Integer docId) {
        Map map = paramMap();
        map.put("contractId", number);
        map.put("docId", docId);
        SqlMapClient client = IbatisTemplate.getSqlMapClient();
        try {
            client.startTransaction();

            client.delete(NAMESPACE + "deleteDocRelation", map);

            client.delete(NAMESPACE_DOC + "deleteDocument", map);

            client.commitTransaction();
        } catch (SQLException ex) {
            Logger.getLogger(ContractImpl.class.getName()).log(Level.SEVERE, null, ex);

            /* 遇到异常，返回false,注意：返回之前 finally 内的内容会执行，故不用担心会跳过finally */
            return false;
        } finally {
            try {
                client.endTransaction();
            } catch (SQLException ex) {
                Logger.getLogger(ContractImpl.class.getName()).log(Level.SEVERE, null, ex);
            }
            System.out.println(" * * * " + " finlly " + "  * * * ");
        }

        /* 程序正常结束，返回true */
        return true;
    }

    private static int updateFlowMark(String number, String flowMark) {
        SqlMapClient client = IbatisTemplate.getSqlMapClient();
        try {
            client.startTransaction();

            Map map = paramMap();
            map.put("number", number);
            map.put("flowMark", flowMark);
            client.update(NAMESPACE + "updateFlowMark", map);

            client.commitTransaction();
        } catch (SQLException ex) {
            Logger.getLogger(ContractImpl.class.getName()).log(Level.SEVERE, null, ex);

            /* 遇到异常，返回false,注意：返回之前 finally 内的内容会执行，故不用担心会跳过finally */
            return -1;
        } finally {
            try {
                client.endTransaction();
            } catch (SQLException ex) {
                Logger.getLogger(ContractImpl.class.getName()).log(Level.SEVERE, null, ex);
            }
            System.out.println(" * * * " + " finlly " + "  * * * ");
        }

        /* 程序正常结束，返回true */
        return 1;
    }

    /* 提交 */
    public static int submit(String number) {

        return updateFlowMark(number, "1");
    }

    /* 审核通过 */
    public static int check(String number) {

        return updateFlowMark(number, "100");//
    }

    /* 取消审核 */
    public static int unCheck(String number) {
        if (CheckFlowImpl.checkFlowIsExists()) {
            /* 有审批流，置为99 */
            return updateFlowMark(number, "99");
        } else return updateFlowMark(number, "1");
    }

    /* 主要信息 */
    public static boolean insert(int type, MainInformation emp, String mainNumber) {
        FileUploadBean fileUploadBean = (FileUploadBean) FacesUtils.getManagedBean("fileUploadBean");
        List<ContractDocument> docList = fileUploadBean.getUploadedDocumentList();

        SqlMapClient client = IbatisTemplate.getSqlMapClient();
        try {
            client.startTransaction();
            //client.startBatch();
            /* 设置编号 */
            String maxNumber = buildNumber(type, client);
            emp.setNumber(maxNumber);

            /* 保存mainInfo */
            client.insert(NAMESPACE + "insertMainInformation", emp);

            if (type == 1 && mainNumber != null) {
                Map map = new HashMap();
                map.put("orgCode", LoginParam.getOrg().getCode());
                map.put("contract", mainNumber);
                map.put("suplyContract", maxNumber);
                client.insert(NAMESPACE + "insertContractAndSuplyContractRelation", map);
            }

            saveDoc(client, emp.getNumber(), docList);

            //client.executeBatch();
            client.commitTransaction();
        } catch (SQLException ex) {
            Logger.getLogger(ContractImpl.class.getName()).log(Level.SEVERE, null, ex);

            /* 遇到异常，返回false,注意：返回之前 finally 内的内容会执行，故不用担心会跳过finally */
            return false;
        } finally {
            try {
                client.endTransaction();
            } catch (SQLException ex) {
                Logger.getLogger(ContractImpl.class.getName()).log(Level.SEVERE, null, ex);
            }
            System.out.println(" * * * " + " finlly " + "  * * * ");
        }

        /* 保存后 重新初始化 文档上传bean */
        fileUploadBean.init();

        /* 程序正常结束，返回true */
        return true;
    }

    private static String buildNumber(int type, SqlMapClient client) throws SQLException {
        Map map = paramMap();
        map.put("type", type);
        Integer max = (Integer) client.queryForObject(NAMESPACE + "maxNumberOfContract", map);
        if (max == null) {
            max = 0;
        }
        return String.valueOf(type) + String.format("%06d%n", max + 1).trim();
    }

    private static Map paramMap() {
        Map map = new HashMap();
        map.put("orgCode", LoginParam.getOrg().getCode());
        return map;
    }

//    public static boolean update(MainInformation emp) {
//        IbatisTemplate.update(NAMESPACE + "updateMainInformation", emp);
//        return true;
//    }
    public static boolean update(MainInformation emp) {
        FileUploadBean fileUploadBean = (FileUploadBean) FacesUtils.getManagedBean("fileUploadBean");
        List<ContractDocument> docList = fileUploadBean.getUploadedDocumentList();

        System.out.println(" * * * " + "docList size = " + docList.size() + "  * * * ");

        SqlMapClient client = IbatisTemplate.getSqlMapClient();
        try {
            client.startTransaction();
            //client.startBatch();

            client.update(NAMESPACE + "updateMainInformation", emp);

            /* 保存附件 */
            saveDoc(client, emp.getNumber(), docList);

            //client.executeBatch();
            client.commitTransaction();
        } catch (SQLException ex) {
            Logger.getLogger(ContractImpl.class.getName()).log(Level.SEVERE, null, ex);

            /* 遇到异常，返回false,注意：返回之前 finally 内的内容会执行，故不用担心会跳过finally */
            return false;
        } finally {
            try {
                client.endTransaction();
            } catch (SQLException ex) {
                Logger.getLogger(ContractImpl.class.getName()).log(Level.SEVERE, null, ex);
            }
            System.out.println(" * * * " + " finlly " + "  * * * ");
        }

        /* 保存后 重新初始化 文档上传bean */
        fileUploadBean.init();

        /* 程序正常结束，返回true */
        return true;
    }

    public static void updateContractFlowMark(MainInformation emp) {
        //修改合同审批状态
        IbatisTemplate.update("updateContractFlowMark", emp);
    }

    /* 删除合同（包括 基本信息、付款计划、补充合同（如果是主合同的话）等） */
    public static boolean deleteContract(String number) {
        SqlMapClient sqlMap = IbatisTemplate.getSqlMapClient();
        try {
            Map map = paramMap();
            map.put("number", number);

            sqlMap.startTransaction();
            sqlMap.startBatch();

            /* 删除合同（如果是主合同，不包括相关连的补充合同） */
            delContract(sqlMap, map);

            /* 如果是主合同，删除所属的补充合同 */
            if (number.startsWith("0")) {

                /* 获取所属的补充合同列表 */
                List<String> supplyContractNumberList = sqlMap.queryForList(NAMESPACE + "querySupplyNumberList", map);

                Map supply = paramMap();
                for (String num : supplyContractNumberList) {
                    supply.put("number", num);

                    /* 删除补充合同 */
                    delContract(sqlMap, supply);
                }

                /*删除 主合同与补充合同 关系 */
                sqlMap.delete(NAMESPACE + "deleteSupplyRelate", map);

            }

            sqlMap.executeBatch();
            sqlMap.commitTransaction();
        } catch (SQLException ex) {
            Logger.getLogger(ContractImpl.class.getName()).log(Level.SEVERE, null, ex);
            return false;
        } finally {
            try {
                sqlMap.endTransaction();
            } catch (SQLException ex) {
                Logger.getLogger(ContractImpl.class.getName()).log(Level.SEVERE, null, ex);
            }
        }
        return true;
    }

    private static void delContract(SqlMapClient sqlMap, Map map) throws SQLException {
        /* 删除主要信息 */
        sqlMap.delete(NAMESPACE + "deleteMainInfo", map);

        /* 删除合同内容 */
        sqlMap.delete(NAMESPACE + "deleteContractContent", map);

        /* 删除合同条款 */
        sqlMap.delete(NAMESPACE + "deleteContractItem", map);

        /* 删除付款计划 */
        sqlMap.delete(NAMESPACE + "deletePayInformation", map);

        /* 删除其他事项 */
        sqlMap.delete(NAMESPACE + "deleteMatter", map);

        /* 删除违约责任 */
        sqlMap.delete(NAMESPACE + "deleteDuty", map);

        /* 删除附件及对应关系 */
        List<Integer> docIdList = sqlMap.queryForList(NAMESPACE + "queryDocIdList", map);

        for (Integer id : docIdList) {

            sqlMap.delete(NAMESPACE + "deleteDocument", id);
        }
        sqlMap.delete(NAMESPACE + "deleteDocRelationByContractNumber", map);
    }

    public static void saveContent(List<ContractContent> datali) {
        if (!Null.check(datali)) {
            Map map = paramMap();
            map.put("number", datali.get(0).getNumber());
            IbatisTemplate.delete(NAMESPACE + "deleteContractContent", map);
            IbatisTemplate.insertList(NAMESPACE + "insertContractContent", datali);
        }
    }

    public static void savePayInformation(List<PayInformation> datali) {
        if (!Null.check(datali)) {
            Map map = paramMap();
            map.put("number", datali.get(0).getNumber());
            IbatisTemplate.delete(NAMESPACE + "deletePayInformation", map);
            IbatisTemplate.insertList(NAMESPACE + "insertContractPayInformation", datali);
        }
    }

    public static void saveContractItem(List<ContractItem> datali) {
        if (!Null.check(datali)) {
            Map map = paramMap();
            map.put("number", datali.get(0).getNumber());
            IbatisTemplate.delete(NAMESPACE + "deleteContractItem", map);
            IbatisTemplate.insertList(NAMESPACE + "insertContractItem", datali);
        }
    }

    public static void saveMatter(List<Matter> datali) {
        if (!Null.check(datali)) {
            Map map = paramMap();
            map.put("number", datali.get(0).getNumber());
            IbatisTemplate.delete(NAMESPACE + "deleteMatter", map);
            IbatisTemplate.insertList(NAMESPACE + "insertMatter", datali);
        }
    }

    public static void saveDuty(List<Duty> datali) {
        if (!Null.check(datali)) {
            Map map = paramMap();
            map.put("number", datali.get(0).getNumber());
            IbatisTemplate.delete(NAMESPACE + "deleteDuty", map);
            IbatisTemplate.insertList(NAMESPACE + "insertDuty", datali);
        }
    }

    public static List<MainInformation> queryContractList(Map map) {
        if (map == null) map = new HashMap();
        map.put("orgCode", LoginParam.getOrg().getCode());
        map.put("iyear", LoginParam.getIyear());
        return IbatisTemplate.queryForList(NAMESPACE + "queryMainInformation", map);
    }

    public static List<MainInformation> queryContractListForCheck(Map map) {
        if (map == null) map = new HashMap();
        map.put("orgCode", LoginParam.getOrg().getCode());
        map.put("iyear", LoginParam.getIyear());
        map.put("checkFlag", "flag");
        return IbatisTemplate.queryForList(NAMESPACE + "queryMainInformation", map);
    }

    public static List<MainInformation> queryContractListIsChecked(Map map) {
        if (map == null) map = new HashMap();
        map.put("orgCode", LoginParam.getOrg().getCode());
        map.put("iyear", LoginParam.getIyear());
        map.put("flowMark", "100");//审核通过的合同
        return IbatisTemplate.queryForList(NAMESPACE + "queryMainInformation", map);
    }

    public static List<ContractContent> queryContractContentList(String number) {
        Map map = paramMap();
        map.put("number", number);
        return IbatisTemplate.queryForList(NAMESPACE + "queryContractContentList", map);
    }

    public static List<ContractContent> queryContractContentListForExec(String number) {
        Map map = paramMap();
        map.put("number", number);
        return IbatisTemplate.queryForList(NAMESPACE + "queryContractContentListForExec", map);
    }

    public static List<ContractItem> queryContractItemList(String str) {
        Map map = paramMap();
        map.put("number", str);
        return IbatisTemplate.queryForList(NAMESPACE + "queryContractItemList", map);
    }

    public static List<PayInformation> queryPayInformationList(String str) {
        Map map = paramMap();
        map.put("number", str);
        return IbatisTemplate.queryForList(NAMESPACE + "queryPayInformationList", map);
    }

    public static List<Matter> queryMatterList(String str) {
        Map map = paramMap();
        map.put("number", str);
        return IbatisTemplate.queryForList(NAMESPACE + "queryMatterList", map);
    }

    public static List<Duty> queryDutyList(String str) {
        Map map = paramMap();
        map.put("number", str);
        return IbatisTemplate.queryForList(NAMESPACE + "queryDutyList", map);
    }

    public static void insertRelation(Map map) {
        map.put("orgCode", LoginParam.getOrg().getCode());
        IbatisTemplate.insert(NAMESPACE + "insertContractAndSuplyContractRelation", map);
    }

    public static void deleteRelation(String suplyNumber) {
        Map map = paramMap();
        map.put("suplyContract", suplyNumber);
        IbatisTemplate.insert(NAMESPACE + "deleteContractAndSuplyContractRelation", map);
    }

    public static MainInformation queryMainContractBySuplyContractNumber(String suplyNumber) {
        Map map = paramMap();
        map.put("suplyContract", suplyNumber);
        return (MainInformation) IbatisTemplate.query(NAMESPACE + "queryMainContractBySuplyContractNumber", map);
    }

    public static MainInformation queryMainInfoByNumber(String number) {
        Map map = paramMap();
        map.put("number", number);
        map.put("iyear", LoginParam.getIyear());
        return (MainInformation) IbatisTemplate.query(NAMESPACE + "queryMainInfoByNumber", map);
    }

    private static void testDuty() {
        Duty duty = new Duty();
        duty.setNumber("number");
        duty.setDuty("duty");
        duty.setMemo("memo");
        duty.setFlag(0);
        List li = new ArrayList();
        li.add(duty);
        saveDuty(li);
    }

    private static void testMatter() {
        Matter matter = new Matter();
        matter.setNumber("number");
        matter.setMatter("matter");
        matter.setMemo("memo");
        matter.setFlag(0);

        List li = new ArrayList();
        li.add(matter);
        saveMatter(li);
    }

    private static void testItem() {
        ContractItem item = new ContractItem();
        item.setNumber("number");
        item.setTermtype("0");
        item.setOther("other");
        item.setFlag(0);

        List li = new ArrayList();
        li.add(item);
        saveContractItem(li);
    }

    private static void testPayInformation() {
        PayInformation info = new PayInformation();
        info.setNumber("number");
        info.setPaytime(new Date());
        info.setMoney(100d);
        info.setMemo("memo");
        info.setFlag(0);
        List li = new ArrayList();
        li.add(info);
        savePayInformation(li);
    }

    private static void testContent() {
        ContractContent content = new ContractContent();
        content.setNumber("number");
        content.setCode("code");
        content.setName("name");
        content.setTecrequire("");
        content.setCount(1.0);
        content.setPrice(10d);
        content.setMemo("");
        content.setFlag(0);

        List list = new ArrayList();
        list.add(content);
        saveContent(list);
    }

    private static void testMainInfo() {
        //Integer maxCode = maxCode();
        //System.out.println("maxCode = " + maxCode);
        MainInformation mainInfo = new MainInformation();
        mainInfo.setContractTypeCode("typeCode");
        mainInfo.setNumber("number");
        mainInfo.setCname("cname");
        mainInfo.setOrderdate(new Date());
        mainInfo.setAddress("address");
        mainInfo.setStart(new Date());
        mainInfo.setDeadline(new Date());
        mainInfo.setNameA("nameA");
        mainInfo.setNameAstand("nameAstand");
        mainInfo.getPartner().setId("id");
        mainInfo.getPartner().setName("pname");
        mainInfo.getPartner().setLegalPerson("legalPerson");
        mainInfo.setTarget(new BigDecimal(0d));
        mainInfo.setQuality_margin(new BigDecimal(0d));
        mainInfo.setPenalty(new BigDecimal(0d));
        mainInfo.setOther("other");
        mainInfo.setPay("pay");
        mainInfo.setWarranty(new Date());

        //insert(1, mainInfo);
        update(mainInfo);
        //IbatisTemplate.update(NAMESPACE + "updateMainInformation", mainInfo);
    }

    public static void testDoc() throws SQLException {
        SqlMapClient client = IbatisTemplate.getSqlMapClient();
        client.startTransaction();

        List<ContractDocument> docList = new ArrayList();
        docList.add(newDoc());
        docList.add(newDoc());
        docList.add(newDoc());
        saveDoc(client, "0000001", docList);

        client.commitTransaction();
    }

    private static ContractDocument newDoc() {
        ContractDocument doc = new ContractDocument();
        doc.setUserName("name1");
        doc.setUrl("");
        doc.setUploadDate(new Date());
        doc.setTitle("");
        doc.setDocSize("11B");
        doc.setDescription("");
        return doc;
    }

    public static void main(String[] args) throws SQLException {
        //testContent();
        //testPayInformation();
        //testItem();
        //testMatter();
        //testDuty();
//        Map map = new HashMap();
//        map.put("flag", 0);
//        queryContractList(map);
        // testMainInfo();
        testDoc();
    }
}
